<template>
    <div class="all_box"  style="">
        <div id="energy"></div>
        <div class="return" @click="back">
            <a-icon type="left" />
        </div>
        <!-- <div class="fixed_left_data">
            数据展示块{{activBox}}
        </div>
        <div class="fixed_right_data">
            数据展示块{{unitName}}
        </div> -->
        <div id="" @click.stop="" style="z-index: 9999;">
            <a-modal ref="aModal" v-model="visible" :bodyStyle="{padding:0}" :footer="null" :closable="false" :centered="true" width="80%">
                <template slot="title">
                    <div id="" style="display: flex;justify-content: space-between;background-color: rgba(0,0,0,0);">
                        <span></span>
                        <a-icon type="close" class="close"  @click.stop="visible=false"/>
                    </div>
                </template>
                <template slot="footer">
                    <!-- <a-button key="back" @click.stop="visible=false">
                        关闭
                    </a-button> -->
                </template>
                <div class="content_box" v-if="visible">
                    <detail_3d></detail_3d>
                </div>
            </a-modal>
        </div>
    </div>
</template>

<script>
    import * as THREE from 'three'
    import {
        OrbitControls
    } from "three/examples/jsm/controls/OrbitControls"
    import {
        OBJLoader
    } from 'three/examples/jsm/loaders/OBJLoader';
    import {
        MTLLoader
    } from 'three/examples/jsm/loaders/MTLLoader'
    import Stats from 'three/examples/jsm/libs/stats.module.js'
    import diban from "/src/pages/home/3dModels/diban.png"
    import direct from "/src/pages/home/3dModels/direct.png"
    import qiang from "/src/pages/home/3dModels/qiang.png"
    import mian1 from "/src/pages/home/3dModels/mian1.jpg"
    import mian2 from "/src/pages/home/3dModels/mian2.jpg"
    import mian3 from "/src/pages/home/3dModels/mian3.jpg"
    import mian4 from "/src/pages/home/3dModels/mian4.jpg"
    import shu1 from "/src/pages/home/3dModels/shu1.png"
    import detail_3d from "./components/detail.vue"
    export default {
        components: {
            detail_3d
        },
        data() {
            return {
                activBox:'',
                unitName:'',
                visible:false
            }
        },
        created() {},
        mounted() {
            // var stats = initStats();
            var scene, camera, renderer, controls, light;
            let _this= this
            
            // 初始化场景
            function initScene() {
                scene = new THREE.Scene();
                scene.fog = new THREE.Fog(scene.background, 1000, 30000);
                let mesh = []//网格模型对象Mesh
                function choose(event) {
                    console.log('camera=====>',camera);
                event.preventDefault();
                  var Sx = event.clientX; //鼠标单击位置横坐标
                  var Sy = event.clientY; //鼠标单击位置纵坐标
                  let dom = document.getElementById('energy')
                  //屏幕坐标转WebGL标准设备坐标
                  var x = (Sx / (dom.offsetWidth+5)) * 2 - 1; //WebGL标准设备横坐标
                  var y = -(Sy / (dom.offsetHeight+84)) * 2 + 1; //WebGL标准设备纵坐标
                  
                  //创建一个射线投射器`Raycaster`
                  var raycaster = new THREE.Raycaster();
                  //通过鼠标单击位置标准设备坐标和相机参数计算射线投射器`Raycaster`的射线属性.ray
                  raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
                  //返回.intersectObjects()参数中射线选中的网格模型对象
                  // 未选中对象返回空数组[],选中一个数组1个元素，选中两个数组两个元素
                  var intersects = raycaster.intersectObjects(scene.children,true);
                  console.log("射线投射器返回的对象", intersects);
                
                  // intersects.length大于0说明，说明选中了模型
                  if (intersects.length > 0) {
                      let custType = intersects[0].object.parent?intersects[0].object.parent.custType:''
                      if(intersects[0].object.custType=="jzx" || custType){
                        _this.visible = true
                        setTimeout(function() {
                            
                            let dom = _this.$refs.aModal.$vnode.elm.children[1].children[0].children[1].firstChild
                            dom.style.padding='0 10px 10px 0'
                            dom.style.border='unset'
                            dom.style.background='unset'
                            _this.$refs.aModal.$vnode.elm.children[1].children[0].children[1].style.background='unset'
                        });
                        console.log('====================>>>>',intersects[0].object);
                      }
                  }
                }
                
                setTimeout(function() {
                    addEventListener('dblclick', choose);
                }, 1000);
            }

            // 初始化相机
            function initCamera() {
                camera = new THREE.PerspectiveCamera(45, window.innerWidth / (window.innerHeight-64), 0.1, 8500);
                camera.position.set(3.4982345143620766,2222.164810611707, 3848.9007650130657);
                camera.lookAt(new THREE.Vector3(0, 0, 0));
            }

            // 初始化灯光
            function initLight() {
                var directionalLight = new THREE.DirectionalLight(0xffffff, 0.1); //模拟远处类似太阳的光源
                directionalLight.color.setHSL(0.1, 1, 0.95);
                directionalLight.position.set(0, 200, 0).normalize();
                scene.add(directionalLight);
                

                var ambient = new THREE.AmbientLight(0xffffff, 1); //AmbientLight,影响整个场景的光源
                ambient.position.set(0, 0, 0);
                scene.add(ambient);
            }

            //         // 初始化性能插件
            //         function initStats() {
            //             var stats = new Stats();

            //             stats.domElement.style.position = 'absolute';
            //             stats.domElement.style.left = '0px';
            //             stats.domElement.style.top = '0px';

            //             document.body.appendChild(stats.domElement);
            //             return stats;
            //         }

            // 初始化渲染器
            function initRenderer() {
                renderer = new THREE.WebGLRenderer({
                    antialias: true
                });
                renderer.setSize(window.innerWidth, window.innerHeight - 64);
                renderer.setClearColor(0x0F1726,0);
                let container = document.getElementById('energy');
                container.appendChild(renderer.domElement);
                // 集装箱 , , 0,
                let g = { l:200 , w: 200, h:450  }
                let w=2700
                let l=1800 
                for(let i=0;i<6;i++){
                    // 区域1
                    _this.drawContainer(scene,g ,{x:-w + 500 + (330*i),y:110,z:l - 350 - 300},0,{zone:1,id:i})
                    _this.drawContainer(scene,g ,{x:-w + 500 + (330*i),y:110,z:l - 350 - 900},0,{zone:1,id:i+6})
                }
                for(let i=0;i<6;i++){
                    // 区域2
                    _this.drawContainer(scene,g ,{x:-w + 500 + (330*i),y:110,z:-l + 350 + 300},0,{zone:2,id:i})
                    _this.drawContainer(scene,g ,{x:-w + 500 + (330*i),y:110,z:-l + 350 + 900},0,{zone:2,id:i+6})
                }
                for(let i=0;i<6;i++){
                    // 区域3
                    _this.drawContainer(scene,g ,{x:w - 580 - (330*i),y:110,z:-l + 350 + 300},0,{zone:3,id:i})
                    _this.drawContainer(scene,g ,{x:w - 580 - (330*i),y:110,z:-l + 350 + 900},0,{zone:3,id:i+6})
                }
                for(let i=0;i<6;i++){
                    
                    // 区域4
                    _this.drawContainer(scene,g ,{x:w - 580 - (330*i),y:110,z:l - 350 - 300},0,{zone:4,id:i})
                    _this.drawContainer(scene,g ,{x:w - 580 - (330*i),y:110,z:l - 350 - 900},0,{zone:4,id:i+6})
                    
                    // _this.drawContainer(scene,g ,{x:w - 680 - (700*i),y:110,z:l - 250 - 300},Math.PI / 2)
                    // _this.drawContainer(scene,g ,{x:w - 680 - (700*i),y:110,z:l - 250 - 700},Math.PI / 2)
                    // _this.drawContainer(scene,g ,{x:w - 680 - (700*i),y:110,z:l - 250 - 1100},Math.PI / 2)
                    // _this.drawContainer(scene,g ,{x:w - 580 - (330*i),y:110,z:-l + 350 + 900},Math.PI / 2)
                }
                
                // 悬浮提示框
                let currentIntersected;
                let pieceW = ''
                let tooltip = document.createElement('div');
                tooltip.style.position = 'fixed';
                tooltip.style.zIndex = '999';
                tooltip.style.background = 'rgba(0,0,0,0.38)';
                tooltip.style.padding = '8px';
                tooltip.style.borderRadius = '5px';
                tooltip.style.visibility = 'hidden';
                container.appendChild(tooltip);
                // _this.drawContainer(scene, g,{x:400,y:110,z:-300},Math.PI / 2)
                // 监听鼠标移动事件，显示悬浮提示框 点击 mouseup 触碰mousemove
                renderer.domElement.addEventListener('mousemove', function(event) {
                  // let mouse = new THREE.Vector2();
                  let dom = document.getElementById('energy')
                  let x = (event.clientX / (dom.offsetWidth +5)) * 2 - 1;
                  let y = -(event.clientY / (dom.offsetHeight + 84)) * 2 + 1;
                  let raycaster = new THREE.Raycaster();
                  raycaster.setFromCamera(new THREE.Vector2(x, y), camera);
                  let intersects = raycaster.intersectObjects(scene.children, true);
                  if (currentIntersected) {
                    currentIntersected.material.color = pieceW;
                    // console.log(currentIntersected);
                    currentIntersected = null;
                  }
                  if (intersects.length > 0) {
                  // console.log(intersects[0].object.parent);
                    let custType = intersects[0].object.parent?intersects[0].object.parent.custType:''
                      if(intersects[0].object.custType == 'jzx' || custType){
                            tooltip.style.visibility = 'visible';
                            tooltip.style.left = (event.clientX + 20) + 'px';
                            tooltip.style.top = (event.clientY - 20) + 'px';
                            // tooltip.innerHTML = intersects[0].object.name;
                            
                            // 触碰变颜色
                            currentIntersected = custType?intersects[0].object.parent:intersects[0].object;
                            pieceW = currentIntersected.material.color
                            const color1 = new THREE.Color( "rgb(140,240,255)");
                            currentIntersected.material.color = color1;
                            tooltip.innerHTML=`
                                <div>
                                    <div style="color:#fff">${currentIntersected.cunstName}</div>
                                    <div style="font-size:12px;margin-top:5px">
                                        <span style="color:#fff">状态：</span>
                                        <span style="color:rgb(64, 230, 254)">正常</span>
                                    </div>
                                </div>
                            `
                            
                            // currentIntersected.material.opacity = 0.7;
                      }else{
                          tooltip.style.visibility = 'hidden';
                      }
                  } else {
                    tooltip.style.visibility = 'hidden';
                  }
                });
            }
            //创建地板
            function createFloor() {
                var loader = new THREE.TextureLoader();
                loader.load(diban, function(texture) {
                    texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
                    texture.repeat.set(25, 15);
                    var floorGeometry = new THREE.BoxGeometry(10000, 6000, 20);
                    var floorMaterial = new THREE.MeshBasicMaterial({
                        map: texture,
                        // color:'#ddd',
                        side: THREE.DoubleSide
                    });
                    var floor = new THREE.Mesh(floorGeometry, floorMaterial);
                    floor.position.y = -0.5;
                    floor.rotation.x = Math.PI / 2;
                    floor.name = "地面";
                    scene.add(floor);
                    loader.load(direct, function(texture2) {
                        texture2.wrapS = texture2.wrapT = THREE.RepeatWrapping;
                        texture2.repeat.set(1, 1);
                        let floorGeometry2 = new THREE.BoxGeometry(5400 , 3600, 10);
                        let floorMaterial2 = new THREE.MeshBasicMaterial({
                            map: texture2,
                            transparent: true
                        });
                        let floor2 = new THREE.Mesh(floorGeometry2, floorMaterial2);
                        floor2.position.y = 15;
                        floor2.position.x = 0;
                        floor2.position.z = 0;
                        floor2.rotation.x = Math.PI / 2;
                        // floor2.rotation.z = Math.PI / 2;
                        floor2.name = "地面";
                        scene.add(floor2);
                    });
                });
                //创建墙
                createCubeWall(1, 150, 3600, 0, new THREE.MeshPhongMaterial({color: 0xefefef}), -2700, 100, 0, "墙面");
                createCubeWall(1, 150, 3600, 1, new THREE.MeshPhongMaterial({color: 0xefefef}), 2700, 100, 0, "墙面");
                createCubeWall(1, 150, 5400, 1.5, new THREE.MeshPhongMaterial({color: 0xefefef}), 0, 100, -1800, "墙面");
                createCubeWall(1, 150, 5400, 1.5, new THREE.MeshPhongMaterial({color: 0xefefef}), 0, 100, 1800, "墙面");
            }
            //创建墙
            function createCubeWall(width, height, depth, angle, material, x, y, z, name){
                var loader = new THREE.TextureLoader();
                loader.load(qiang, function(texture) {
                    texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
                    texture.repeat.set(depth/300, 1);
                    var floorMaterial = new THREE.MeshBasicMaterial({
                        map: texture,
                        transparent: true,
                        side: THREE.DoubleSide,
                    });
                    var cubeGeometry = new THREE.BoxGeometry(width, height, depth );
                    
                    var cube = new THREE.Mesh( cubeGeometry, floorMaterial );
                    cube.position.x = x;
                    cube.position.y = y;
                    cube.position.z = z;
                    cube.rotation.y += angle*Math.PI;  //-逆时针旋转,+顺时针
                    cube.name = name;
                    scene.add(cube);
                }, () => {
                    console.log(666);
                }, (err) => {
                    console.warn(err);
                });
                
            }
            // 初始化模型
            function initContent() {
                createFloor();
            }
            // 初始化轨迹球控件
            function initControls() {
                controls = new OrbitControls(camera, renderer.domElement);
                controls.enableDamping = true;
                controls.dampingFactor = 0.5;
                // 视角最小距离
                controls.minDistance = 200;
                // 视角最远距离
                controls.maxDistance = 5000;
                // 最大角度
                controls.maxPolarAngle = Math.PI / 3;
                controls.minPolarAngle = Math.PI / 3;
            }

            // 更新控件
            function update() {
                // stats.update();
                // controls.update();
            }

            // 初始化
            function init() {
                initScene();
                initCamera();
                initRenderer();
                initContent();
                initLight();
                initControls();
                document.addEventListener('resize', onWindowResize, false);
            }

            // 窗口变动触发的方法
            function onWindowResize() {
                camera.aspect = window.innerWidth / window.innerHeight;
                camera.updateProjectionMatrix();
                renderer.setSize(window.innerWidth, window.innerHeight);
            }

            function animate() {
                requestAnimationFrame(animate);
                renderer.render(scene, camera);
                // update();
            }
            
           
            
            init();
            animate();
        },
        methods: {
            back(){
              this.$router.push('/home')  
            },
  // 画单个箱子
            drawBox(scene, box, axes, info,color='') {
              let { l, w, h } = box
              let { x, y, z } = axes
              let geometry = new THREE.BoxGeometry(l, w, h)
              // 箱子图片纹理
              let textureLoader = new THREE.TextureLoader()
              let plasterTexture = textureLoader.load(mian3)
         
         
              let material = new THREE.MeshLambertMaterial({
                // wireframe: true,
                color,
                map: plasterTexture,
                opacity: 1
              })
         
         
              // 根据箱子画出响应 标签
              // this.drawTagPlane(scene, box, axes)
              // 箱子顶部封口
              let cube = new THREE.Mesh(geometry, material)
              cube.position.set(x, y, z)
         
              this.drawTopPlane(cube, box, axes,color)
         
              cube.boxType = 'BOX'
              cube.boxInfo = JSON.stringify(info)
              scene.add(cube)
            },
            // 画集装箱
            drawContainer(scene, box, axes = { x: 0, y: 0, z: 0 },rotate=0,data) {
              let { l, w, h } = box
              let { x, y, z } = axes
              var JGeometry = new THREE.BoxGeometry(l, w, h)
              // 箱子图片纹理
              let textureLoader = new THREE.TextureLoader()
              let plasterTexture = textureLoader.load(mian1)
              var jMmaterial = new THREE.MeshLambertMaterial({
                transparent: true,
                opacity: 1,
                map: plasterTexture,
                side:THREE.DoubleSide,
              })
              var cube = new THREE.Mesh(JGeometry, jMmaterial)
              cube.rotateY(rotate)
              cube.position.set(x, y, z) // 设置立方体坐标
              cube.custType = 'jzx'
              cube.cunstName = `#${(data.zone-1) * 12 + data.id}单元`
                this.drawCePlane(cube, box, axes)
                this.drawCePlane(cube, box, axes)
                //使用canvas增加字体
                let canvas = document.createElement("canvas");
                canvas.width = 100;
                canvas.height = 40;
                let c = canvas.getContext('2d');
                // 矩形区域填充背景
                c.fillStyle = "rgba(0,0,0,0)";
                c.fillRect(0, 0, 100, 40);
                c.beginPath();
                // 文字
                c.beginPath();
                c.translate(50,20);
                c.fillStyle = "#000000"; //文本填充颜色
                c.font = "bold 22px 宋体";//字体样式设置
                c.textBaseline = "middle"; //文本与fillText定义的纵坐标
                c.textAlign = "center"; //文本居中(以fillText定义的横坐标)
                c.fillText(cube.cunstName , 0, 0);
                
                let texture = new THREE.CanvasTexture(canvas);
                //矩形平面
                let geometry = new THREE.PlaneGeometry(150, 55);
                
                let material = new THREE.MeshPhongMaterial({
                    transparent: true,
                    opacity: 1,
                    map: texture, // 设置纹理贴图
                    // side:THREE.DoubleSide,//不设置此项的话，我们只能看到一面字体，当旋转角度后，另外一面不可见
                });
                // 创建一个矩形平面网模型，Canvas画布作为矩形网格模型的纹理贴图
                let mesh = new THREE.Mesh(geometry, material);
                mesh.position.set(0,l/2+13,-60);
                mesh.rotateX(Math.PI / 2) //旋转网格模型
                mesh.rotateY(Math.PI) //旋转网格模型
                mesh.rotateZ(Math.PI) //旋转网格模型
                cube.add(mesh);
              scene.add(cube)
            },
            // 创建一个平面 标签
            drawTagPlane(scene, box, axes) {
              let { l, h, w } = box
              let { x, y, z } = axes
              const geometry = new THREE.PlaneGeometry(20, 15)
              let textureLoader = new THREE.TextureLoader()
              let plasterTexture = textureLoader.load(mian1)
              let material = new THREE.MeshLambertMaterial({
                map: plasterTexture,
                opacity: 1
              })
              const plane = new THREE.Mesh(geometry, material)
              plane.position.set(
                x + (l / 2 - 20) + 1,
                y - w / 2 + 10 + 1,
                z + h / 2 + 1.01
                // 100 - this.cabinetSize.h / 2 + 1
              ) // 偏移设置立方体坐标
              scene.add(plane)
            },
            // 创建一个平面 封口
            drawTopPlane(scene, box, axes,color='') {
              let { l, w, h } = box
              let { x, y, z } = axes
              const geometry = new THREE.PlaneGeometry(h, w)
              let textureLoader = new THREE.TextureLoader()
              let plasterTexture = textureLoader.load(mian4)
              let material = new THREE.MeshLambertMaterial({
                  color,
                map: plasterTexture,
                opacity: 1
              })
              const plane = new THREE.Mesh(geometry, material)
              const plane2 = new THREE.Mesh(geometry, material)
              plane.rotateY(-Math.PI / 2) //旋转网格模型
              plane2.rotateY(-Math.PI / 2 * -45) //旋转网格模型
              plane.position.set(-l/2-0.5,0,0) // 偏移设置立方体坐标
              plane2.position.set(l/2+0.5,0,0) // 偏移设置立方体坐标
              scene.add(plane)
              scene.add(plane2)
            },
            // 创建2个平面 封口
            drawCePlane(scene, box, axes) {
              let { l, w, h } = box
              let { x, y, z } = axes
              const geometry = new THREE.PlaneGeometry(l, w)
              let textureLoader = new THREE.TextureLoader()
              let plasterTexture = textureLoader.load(mian2)
              let material = new THREE.MeshLambertMaterial({
                transparent: true,
                map: plasterTexture,
                opacity:1,
                side:THREE.DoubleSide,
              })
              const plane = new THREE.Mesh(geometry, material)
              const plane2 = new THREE.Mesh(geometry, material)
              // plane.rotateX(-Math.PI / 2) //旋转网格模型
              plane.position.set(0, 0, h/2  +  1) // 偏移设置立方体坐标
              plane2.position.set(0, 0, -h/2 -1 ) // 偏移设置立方体坐标
              plane2.rotateY(-Math.PI / 2 * 90) //旋转网格模型
              scene.add(plane)
              scene.add(plane2)
            },
            //  圆立体
            drawSphere(scene) {
              // 球体网格模型
              var geometry2 = new THREE.SphereGeometry(20, 20, 20)
              var material2 = new THREE.MeshLambertMaterial({
                color: 0xfdd500
              })
              var mesh2 = new THREE.Mesh(geometry2, material2) //网格模型对象Mesh
              // 设置 坐标
              mesh2.position.set(200, 100, 100)
              scene.add(mesh2)
            },
            sceneControls(scene, camera, renderer) {
              // 控制器渲染
              var controls = new OrbitControls(camera, renderer.domElement)
              controls.addEventListener('change', function() {
                // 直接渲染
                renderer.render(scene, camera) //渲染
              })
            }
        }
    }
</script>

<style scoped="scoped" lang="less">
    .all_box{
        background-image: url(./3dModels/3dBG.jpg);background-size: 100% 100%;
        .return{
            position: fixed;
            z-index: 9;
            color: #fff;
            left:30px;
            top: 90px;
            width: 50px;
            height: 50px;
            text-align: center;
            line-height: 50px;
            border-radius: 50%;
            background-color: rgba(0,0,0,0.33);
            cursor: pointer;
        }
    }
    .fixed_left_data{
        position: fixed;
        width: 22%;
        height: calc(100% - 64px);
        top: 64px;
        left: 0;
        background-color: rgba(0,0,0,0.5);
        color: #fff;
    }
    .fixed_right_data{
        color: #fff;
        position: fixed;
        width: 22%;
        height: calc(100% - 64px);
        top: 64px;
        right: 0;
        background-color: rgba(0,0,0,0.5);
    }
    .close{
        color: #666;
        cursor: pointer;
    }
    .close:hover{
        color: rgb(64, 230, 254);
    }
</style>
